﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using WindowsGame.Library;

namespace WindowsGame.Components
{
	public class ThrustComponent : BaseGameComponent
	{
		private Texture2D texture;
		private Vector4[] engineOffsets;
		private Int32 preferredWindowWidth;
		private Int32 preferredWindowHeight;
		private Boolean showThrust = false;
		private const Single ninetyDegrees = (float)(Math.PI / 2.0);

		public override void LoadContent()
		{
			texture = Engine.Content.Load<Texture2D>(TextureName);
		}

		public void LoadContent(Vector4[] engineOffsets, Int32 preferredWindowWidth, Int32 preferredWindowHeight)
		{
			this.engineOffsets = engineOffsets;
			this.preferredWindowWidth = preferredWindowWidth;
			this.preferredWindowHeight = preferredWindowHeight;
		}

		public Vector3 Update(TimeSpan elapsedTime, Boolean thrust, Vector3 rotation, Vector3 velocity)
		{
			Vector3 acceleration = Vector3.Zero;
			if (thrust)
			{
				showThrust = true;
				ThrustFrame = (ThrustFrame + (elapsedTime.TotalSeconds * ThrustConstant));
				if (ThrustFrame > ThrustConstant)
					ThrustFrame = ThrustConstant;

				Single x = (Single)(-ThrustPower * ThrustFactor * Math.Sin(rotation.Z));
				Single y = (Single)(ThrustPower * ThrustFactor * Math.Cos(rotation.Z));

				Vector2 thrustDirection = new Vector2(x, y);
				acceleration = new Vector3(thrustDirection.X, thrustDirection.Y, 0);
			}
			else
			{
				ThrustFrame += (elapsedTime.TotalSeconds * ThrustConstant);
				if (ThrustFrame > ThrustMaximum)
				{
					showThrust = false;
					ThrustFrame = 0;
				}
			}

			acceleration -= velocity * BleedVelocity;
			return acceleration;
		}

		public void Draw(Matrix worldMatrix, Vector3 rotation)
		{
			if (!showThrust)
			{
				return;
			}

			Matrix viewMatrix = Engine.Camera.ViewMatrix;
			Matrix projectionMatrix = Engine.Camera.ProjectionMatrix;
			Matrix wvp = worldMatrix * viewMatrix * projectionMatrix;
			Rectangle rect = new Rectangle(((Int32)ThrustFrame) * 64, 0, 64, 16);

			Engine.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
			foreach (Vector4 engineOffset in engineOffsets)
			{
				Vector4 source = Vector4.Transform(engineOffset, wvp);
				Vector2 source2D = new Vector2((Int32)((source.X / source.W + 1f) / 2f * preferredWindowWidth), (int)((-source.Y / source.W + 1f) / 2f * preferredWindowHeight));

				Engine.SpriteBatch.Draw(texture, source2D, rect, Color.White, -rotation.Z + ninetyDegrees, new Vector2(2, 8), 1f, SpriteEffects.None, 0.1f);
			}
			Engine.SpriteBatch.End();
		}

		public String TextureName		{ get; set; }
		public Double ThrustFrame		{ get; set; }
		public Int32  ThrustConstant	{ get; set; }
		public Int32  ThrustMaximum		{ get; set; }
		public Single ThrustFactor		{ get; set; }
		public Int32  ThrustPower		{ get; set; }
		public Single BleedVelocity		{ get; set; }
	}
}